package cn.jinbyte.data.changelog.wapper;

import cn.jinbyte.data.changelog.ChangeType;
import cn.jinbyte.data.changelog.annotation.LogProp;
import cn.jinbyte.data.changelog.convert.ChangeConvert;
import lombok.Getter;
import lombok.SneakyThrows;
import lombok.experimental.SuperBuilder;

import java.util.StringJoiner;

/**
 * 基础类型属性内容差异包装器
 */
@Getter
@SuperBuilder
public class PropChangeWrapper extends ChangeWrapper {
    /**
     * 旧值
     */
    private Object oldValue;
    /**
     * 新值
     */
    private Object newValue;

    public String toLogString(ChangeType cType) {
        StringJoiner desc = new StringJoiner("");
        LogProp logProp = propField.getAnnotation(LogProp.class);
        String name = logProp.name();
        String nameWrapper = logProp.nameWrapper();
        boolean logFull = logProp.logFull();
        String[] split = nameWrapper.split(" ");
        switch (cType) {
            case ADD:
                desc.add(prop(logProp)).add(": ").add(convert(logProp, newValue));
                break;
            case DELETE:
                desc.add(prop(logProp)).add(": ").add(convert(logProp, oldValue));
                break;
            case UPDATE:
                if (logFull) {
                    desc.add(prop(logProp)).add(": 由'").add(convert(logProp, oldValue)).add("' 变更为 '").add(convert(logProp, newValue)).add("'");
                } else {
                    desc.add("更新了").add(prop(logProp));
                }
                break;
        }
        return desc.toString();
    }

    public static String prop(LogProp logProp) {
        String name = logProp.name();
        String nameWrapper = logProp.nameWrapper();
        String[] split = nameWrapper.split(" ");
        return logProp.name() + split[0] + name + split[1];
    }

    @SneakyThrows
    public static String convert(LogProp logProp, Object value) {
        Class<? extends ChangeConvert> convertClass = logProp.convert();
        ChangeConvert changeConvertInstance = convertClass.getDeclaredConstructor().newInstance();
        return changeConvertInstance.convert(value);
    }
}